from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.deps import get_current_user, get_db, get_tenant_id
from app.models.user import User
from app.schemas.permission import (
    PermissionCreate,
    PermissionUpdate,
    PermissionResponse,
    PermissionTreeResponse,
    MenuPermissionResponse
)
from app.schemas.base import ResponseModel, PaginationResponse
from app.services.permission import permission_service

router = APIRouter()


@router.get("/", response_model=ResponseModel, summary="获取权限列表")
async def get_permissions(
    skip: int = Query(0, ge=0, description="跳过的记录数"),
    limit: int = Query(20, ge=1, le=100, description="每页记录数"),
    keyword: str = Query(None, description="搜索关键词"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """获取权限列表（分页）"""
    permissions, total = await permission_service.get_list(
        db=db,
        tenant_id=tenant_id,
        skip=skip,
        limit=limit,
        keyword=keyword
    )

    response_data = PaginationResponse(
        total=total,
        page=skip // limit + 1,
        page_size=limit,
        pages=(total + limit - 1) // limit,
        items=[PermissionResponse.model_validate(permission) for permission in permissions]
    )

    return ResponseModel(data=response_data)


@router.post("/", response_model=ResponseModel, summary="创建权限")
async def create_permission(
    permission_in: PermissionCreate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """创建新权限"""
    # 检查权限编码是否已存在
    existing = await permission_service.get_by_code(db=db, code=permission_in.code, tenant_id=tenant_id)
    if existing:
        raise HTTPException(status_code=400, detail="权限编码已存在")

    # 如果指定了父权限，检查父权限是否存在
    if permission_in.parent_id > 0:
        parent = await permission_service.get_by_id(db=db, id=permission_in.parent_id)
        if not parent or parent.tenant_id != tenant_id:
            raise HTTPException(status_code=400, detail="父权限不存在")

    permission = await permission_service.create_permission(
        db=db,
        obj_in=permission_in.model_dump(),
        tenant_id=tenant_id
    )
    return ResponseModel(data=PermissionResponse.model_validate(permission))


@router.get("/{permission_id}", response_model=ResponseModel, summary="获取权限详情")
async def get_permission(
    permission_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """根据ID获取权限详情"""
    permission = await permission_service.get_by_id(db=db, id=permission_id)
    if not permission or permission.tenant_id != tenant_id:
        raise HTTPException(status_code=404, detail="权限不存在")

    return ResponseModel(data=PermissionResponse.model_validate(permission))


@router.put("/{permission_id}", response_model=ResponseModel, summary="更新权限")
async def update_permission(
    permission_id: int,
    permission_in: PermissionUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """更新权限信息"""
    permission = await permission_service.get_by_id(db=db, id=permission_id)
    if not permission or permission.tenant_id != tenant_id:
        raise HTTPException(status_code=404, detail="权限不存在")

    # 检查权限编码是否与其他权限冲突
    if permission_in.code and permission_in.code != permission.code:
        existing = await permission_service.get_by_code(db=db, code=permission_in.code, tenant_id=tenant_id)
        if existing:
            raise HTTPException(status_code=400, detail="权限编码已存在")

    # 检查父权限设置
    if permission_in.parent_id is not None:
        if permission_in.parent_id == permission_id:
            raise HTTPException(status_code=400, detail="不能将自己设置为父权限")

        if permission_in.parent_id > 0:
            parent = await permission_service.get_by_id(db=db, id=permission_in.parent_id)
            if not parent or parent.tenant_id != tenant_id:
                raise HTTPException(status_code=400, detail="父权限不存在")

    updated_permission = await permission_service.update_permission(
        db=db,
        db_obj=permission,
        obj_in=permission_in.model_dump(exclude_unset=True)
    )
    return ResponseModel(data=PermissionResponse.model_validate(updated_permission))


@router.delete("/{permission_id}", response_model=ResponseModel, summary="删除权限")
async def delete_permission(
    permission_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """删除权限"""
    try:
        result = await permission_service.delete_permission(
            db=db,
            id=permission_id,
            tenant_id=tenant_id
        )
        if not result:
            raise HTTPException(status_code=404, detail="权限不存在")
        return ResponseModel(data=True, message="删除成功")
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/tree", response_model=ResponseModel, summary="获取权限树")
async def get_permission_tree(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """获取权限树形结构"""
    tree = await permission_service.get_permission_tree(db=db, tenant_id=tenant_id)
    return ResponseModel(data=tree)


@router.get("/menu", response_model=ResponseModel, summary="获取菜单权限")
async def get_menu_permissions(
    visible_only: bool = Query(True, description="仅显示可见菜单"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
    tenant_id: str = Depends(get_tenant_id)
):
    """获取当前用户的菜单权限"""
    menu_tree = await permission_service.get_menu_tree(
        db=db,
        tenant_id=tenant_id,
        visible_only=visible_only
    )
    return ResponseModel(data=menu_tree)